#include "wwdg.h"
#include "led.h"

WWDG_HandleTypeDef WWDG_Handler;

/***************************
* 函数名： WWDG_Init
* 功能：窗口看门狗初始化函数
* 输入：tr：T[6:0] 计数器值
*				wr：W[6:0] 窗口值
*				fprer：分频系数(WDGTB)，仅最低2位有效
*	 Fwwdg=PCLK1/(4096*2^fprer)，一般CLK1=42MHz
* 输出：无

* 窗口值要大于0x40，否则窗口就不存在了
* 分频后计数器时钟：CK_CNT=PCLK1/4096/(2^WDGTB)
* 其中：4096为手册内规定，PCLK1等于APB1时钟
* 		WDGTB为分频因子（0~3），2^WDGTB大小为
*		1、2、4、8
* 窗口计数器是7位递减计数器，最大为0x7F
* 如不使用提前唤醒中断来喂狗，窗口看门狗超时时间：
*   Twwdg=(4096x2^WDGTBx(T[5:0]+1))/PCLK1
* 其中：Twwdg为超时时间，ms
		PCLK1为APB1时钟频率，最大36MHz
		WDGTB为窗口看门狗预分频系数
		T[5:0]为窗口看门狗计数器低6位
* 窗口看门狗使用的APB1时钟，所以需要使能时钟
（IWDG有自己独立的所以不用）
*/
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
	WWDG_Handler.Instance = WWDG;
	WWDG_Handler.Init.Prescaler = fprer;				// 设置分频系数
	WWDG_Handler.Init.Window = wr;							// 设置窗口值
	WWDG_Handler.Init.Counter = tr;							// 设置计数器值
	WWDG_Handler.Init.EWIMode = WWDG_EWI_ENABLE;// 使能提前唤醒中断
	HAL_WWDG_Init(&WWDG_Handler);								// 初始化WWDG
	
}

/*****************************************
* WWDG底层驱动，时钟配置，中断配置
* 该函数会被HAL_WWDG_Init()调用
* hwwdg：窗口看门狗句柄
*****************************************/
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
{
	__HAL_RCC_WWDG_CLK_ENABLE();					// 使能窗口看门狗时钟
	
	HAL_NVIC_SetPriority(WWDG_IRQn,2,3);	// 抢占优先级2，子优先级3
	HAL_NVIC_EnableIRQ(WWDG_IRQn);				// 使能窗口看门狗中断
}

// 窗口看门 狗中断服务函数
void WWDG_IRQHandler(void)
{
	HAL_WWDG_IRQHandler(&WWDG_Handler);		// 调用WWDG公用中断处理函数
}

// 中断服务函数处理过程，会被HAL_WWDG_IRQHandler()调用
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
	HAL_WWDG_Refresh(&WWDG_Handler); // 更新窗口看门狗
	LED2 = !LED2;
}